package com.olt.controller.oltcenter.oltProblemController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.olt.domain.oltCenter.problem.*;
import com.olt.domain.oltTest.ExamPaper;
import com.olt.domain.oltTest.OltProblemGroup;
import com.olt.domain.oltTest.OltTest;
import com.olt.domain.user.OltUser;
import com.olt.result.ErrorEnum;
import com.olt.result.PageResult;
import com.olt.result.Result;
import com.olt.server.dto.PageInput;
import com.olt.server.dto.SelectDto;
import com.olt.server.oltCenter.oltTestService.OltTestService;
import com.olt.server.oltCenter.oltTestService.dto.*;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import util.PageUtil;
import util.ResizeImage;
import util.ResourcePath;
import util.OltFileUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.UUID;

@RestController
public class OltProblemController {
    @Autowired
    OltTestService oltTestService;



    @PostMapping("api/problem/getProblemsGroups")
    public PageResult<OltProblemGroup> getProblemsGroup(@RequestBody PageInput input){
        var res=new PageResult<OltProblemGroup>();
        OltUser user = (OltUser) SecurityUtils.getSubject().getPrincipal();
        PageUtil.setPageRes(res,oltTestService.getOltProblemsGroup(input, user.getUserId()));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @PostMapping("api/problem/saveProblemGroup")
    public Result<String> getProblemsGroup(@RequestBody @Validated ProblemGroupInput input){
        var res=new Result<String>();
        OltUser user = (OltUser) SecurityUtils.getSubject().getPrincipal();
        oltTestService.saveOltProblemGroup(input, user.getUserId());
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @DeleteMapping("api/problem/deleteProblemGroup")
    public Result<String> deleteProblemGroup(@RequestParam("ids") String[] uuids){
        var res=new Result<String>();
        oltTestService.deleteProblemGroup(Arrays.asList(uuids));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @GetMapping("api/problem/getProblemGroupForEdit")
    public Result<ProblemGroupInput> getProblemGroupForEdit(@RequestParam("id")String uuid){
        var res=new Result<ProblemGroupInput>();
        res.setValue(oltTestService.getProblemGroupForEdit(uuid));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @PostMapping("problem/uploadImg")
    public Result<String> uploadAvatar(@RequestParam("uuid")String id,@RequestParam("file")MultipartFile file)throws IOException {
        String path= ResourcePath.getResInstance().ProblemResource+File.separator+id;
        File uploadFiles = new File(path);
        if (!uploadFiles.exists() && !uploadFiles.isDirectory()) {
            uploadFiles.mkdirs();
        }
        File f= OltFileUtil.SaveFile(file);
        String fileName=UUID.randomUUID().toString()+".png";
        File dst=new File( path+File.separator+fileName);
        if(!dst.exists()){
            dst.createNewFile();
        }
        ResizeImage.imageConvertCommon(f,dst,"png");
        f.delete();
        var res=new Result<String>();
        res.setValue(fileName);
        res.setError(ErrorEnum.Success_Http);
        return  res;

    }

    @PostMapping("api/problem/saveProblem")
    public Result<Boolean> saveSelectProblem(@RequestBody JSONObject json
            ,@RequestParam("type") Integer type) {
        var res=new Result<Boolean>();
        var jsonClass= ProblemFactory.getInstance().getClassByType(type);
        var problem= JSON.parseObject(json.toJSONString(),jsonClass);
        if(problem.getProblem().getProblemType()==3){

            if(!oltTestService.saveOjProblem((ProgramProblem) problem)){
                res.setError(ErrorEnum.MyError("错误"));
                return res;
            }
        }
        res.setValue(oltTestService.saveProblem(problem));
        res.setError(ErrorEnum.Success_Http);
        return  res;

    }

    @PostMapping("api/problem/getProblems")
    public Result<ProblemAbstract> getProblems(@RequestBody GetProblemInput input) {
        return oltTestService.getOltProblems(input);

    }

    @GetMapping("api/problem/getProblemsForEdit")
    public Result<ProblemAbstract> getProblems(@RequestParam("uuid") String uuid) {
        var r=new Result<ProblemAbstract>();
        r.setError(ErrorEnum.Success_Http);
        r.setValue(oltTestService.getProblemForEdit(uuid));
        return  r;

    }

    @DeleteMapping("api/problem/deleteProblem")
    public Result<String> deleteProblem(@RequestParam("ids") String[] uuids,@RequestParam("groupId") String groupId){
        var res=new Result<String>();
        oltTestService.deleteProblem(Arrays.asList(uuids),groupId);
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @PostMapping("api/problem/pushProblemToOj")
    public Result<Long> pushProblemToOj(@RequestBody SolutionInput input){
        var res=new Result<Long>();

        res.setValue(oltTestService.pushSolution(input));

        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @GetMapping("api/problem/getSolutionRes")
    public Result<SolutionResOutput> pushProblemToOj(@RequestParam("solutionId")  Long id){
        var res=new Result<SolutionResOutput>();

        res.setValue(oltTestService.getSolutionRes(id));

        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @GetMapping("api/problem/getGroupBySelect")
    public Result<SelectDto<UUID>> getGroupBySelect(){
        var res=new Result<SelectDto<UUID>>();

        OltUser user = (OltUser) SecurityUtils.getSubject().getPrincipal();
        res.setList(oltTestService.getProblemGroupForSelect(user.getUserId()));

        res.setError(ErrorEnum.Success_Http);
        return res;
    }


    @PostMapping("api/problem/saveExamPaper")
    public Result<String> saveExamPaper(@RequestBody SaveExamPaperInput input){
        var res=new Result<String>();
        OltUser user = (OltUser) SecurityUtils.getSubject().getPrincipal();
        res.setValue(oltTestService.saveExamPaper(input, user.getUserId()).toString());

        res.setError(ErrorEnum.Success_Http);
        return res;
    }


    @PostMapping("api/problem/getExamPaper")
    public PageResult<ExamPaper> getExamPaper(@RequestBody PageInput input){
        var res=new PageResult<ExamPaper>();
        OltUser user = (OltUser) SecurityUtils.getSubject().getPrincipal();
        PageUtil.setPageRes(res,oltTestService.getExamPaper(input, user.getUserId()));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @GetMapping("api/problem/getProblemForExam")
    public Result<ProblemForExamDto> getExamProblem (@RequestParam("id")Long id){
        var res=new Result<ProblemForExamDto>();
        res.setValue(oltTestService.getProblemForExam(id));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }


    @PostMapping("api/problem/getTestByClass")
    public PageResult<OltTest> getTestByClass(@RequestBody GetTestInput input){
        var res=new PageResult<OltTest>();
        PageUtil.setPageRes(res,oltTestService.getTestByClass(input));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @GetMapping("api/problem/getPaperForSelect")
    public Result<SelectDto<String>> getPaperForSelect(){
        var res=new Result<SelectDto<String>>();
        OltUser user = (OltUser) SecurityUtils.getSubject().getPrincipal();
        res.setList(oltTestService.getPaperForSelect(user.getUserId()));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @PostMapping("api/problem/saveOltTest")
    public Result<Boolean> saveOltTest(@RequestBody OltTest test){
        var res=new Result<Boolean>();
        OltUser user = (OltUser) SecurityUtils.getSubject().getPrincipal();
        test.setCreateUser(user.getUserId());
        res.setValue(oltTestService.saveOltTest(test));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }
    @GetMapping("api/problem/getTestForEdit")
    public Result<OltTest> getTestForEdit(@RequestParam("id") String id){
        var res=new Result<OltTest>();
        res.setValue(oltTestService.getTestForEdit(id));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }


    @DeleteMapping("api/problem/deleteTest")
    public Result<Boolean> deleteTestById(@RequestParam("id") String id){
        var res=new Result<Boolean>();
        try {
            res.setValue(oltTestService.deleteTestById(id));
            res.setError(ErrorEnum.Success_Http);
        } catch (Exception e) {
           res.setError(ErrorEnum.MyError(e.getMessage()));
        }
        return res;
    }


    @GetMapping("api/problem/getTestSession")
    public Result<String> getTestSession(@RequestParam("id") String id){
        var res=new Result<String>();
        OltUser user = (OltUser) SecurityUtils.getSubject().getPrincipal();
        try {
            res.setValue(oltTestService.getTestSession(id, user.getUserId()));
            res.setError(ErrorEnum.Success_Http);
        } catch (Exception e) {
            res.setError(ErrorEnum.MyError(e.getMessage()));
        }
        return res;
    }


    @PostMapping("api/problem/saveStudentAns")
    public Result<Boolean> saveStudentAns(@RequestBody  UploadStudentAns ans){
        var res=new Result<Boolean>();
        OltUser user = (OltUser) SecurityUtils.getSubject().getPrincipal();
        res.setValue(oltTestService.saveStudentUpload(ans, user.getUserId()));
        res.setError(ErrorEnum.Success_Http);

        return res;
    }

    @GetMapping("api/problem/getScoreSegmented")
    public Result<XYDto<Integer>> getScoreSegmented(@RequestParam("id")String id){
        var res=new Result<XYDto<Integer>>();
        res.setList(oltTestService.getScoreSegmented(id));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @GetMapping("api/problem/getScoreMessage")
    public Result<XYDto<Double>> getScoreMessage(@RequestParam("id")String id){
        var res=new Result<XYDto<Double>>();
        res.setList(oltTestService.getScoreMessage(id));
        res.setError(ErrorEnum.Success_Http);
        return res;
    }

    @GetMapping("download/exportExcel")
    public void exportCorpLoanDemand(@RequestParam("id")String testId, HttpServletResponse response){ ;
            oltTestService.getExcel(testId,response);
    }












}
